package httpx

import (
	"ci-control-backend/common/redis"
	"ci-control-backend/model"
	"ci-control-backend/tools"
	"github.com/pkg/errors"
	"strconv"
	"time"
)

// TokenHeader Token头
const TokenHeader = "X-Token"

// GetLoginUser 从token获取当前登录的用户
func (t *Token) GetLoginUser() (*model.User, error) {
	var user *model.User
	if token := t.context.GetHeader(TokenHeader); token != "" {
		useridStr, err := redis.Get("sk-" + token)
		if err != nil {
			return nil, err
		}
		if useridStr == "" {
			return nil, errors.New("从token读取userid失败")
		}
		userid, err := tools.ParseUint(useridStr) //字符串转整型
		if err != nil {
			return nil, err
		}
		user, err = model.GetUserByID(userid)
		if err != nil {
			return nil, err
		}
		if user == nil {
			return nil, errors.New("用户不存在")
		}
	} else {
		return nil, errors.New("没有token")
	}
	return user, nil
}

// Save 生成并保存token
// user 要保存登录状态的用户
// expiration token过期时间，0为永久保存
func (t *Token) Save(user *model.User, expiration time.Duration) (string, error) {
	token, err := t.create()
	if err != nil {
		return "", err
	}
	//保存token到redis
	userid := strconv.FormatUint(uint64(user.ID), 10)
	if err := redis.Set("sk-"+token, userid, expiration); err != nil {
		return "", err
	}
	if err := redis.Set("uk-"+userid, token, expiration); err != nil {
		return "", err
	}
	return token, nil
}

// ClearOther 清除其他token
func (t *Token) ClearOther() error {
	if token := t.context.GetHeader(TokenHeader); token != "" {
		iUserid, _ := t.context.GetLoginUserid()
		userid := tools.ToString(iUserid)
		tokenList, err := redis.Scan("sk-*")
		if err != nil {
			return err
		}
		for _, key := range tokenList {
			if key != "sk-"+token {
				val, err := redis.Get(key)
				if err != nil {
					return err
				}
				if val == userid {
					err := redis.Del(key)
					if err != nil {
						return err
					}
				}
			}
		}
	} else {
		return errors.New("没有token")
	}
	return nil
}

// create 创建token
func (t *Token) create() (string, error) {
	return tools.RandomStr(64)
}
